#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtTextToSpeech>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlQueryModel>
#include <QOpcUaClient>
#include <QOpcUaProvider>
#include <QItemSelectionModel>
#include <QLabel>

#include "addalarmdialog.h"
#include "qwintspindelegate.h"
#include "qwcomboboxdelegate.h"
#include "qwtexteditdelegate.h"
#include "mydelegate.h"
#include "fromchartview.h"

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow {
    Q_OBJECT

  public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
  protected:
    void resizeEvent(QResizeEvent *event) override;

  public slots:
//! [1.语音功能部分]
    void setRate(int);
    void setVolume(int volume);
    void stateChanged(QTextToSpeech::State state);
    void engineSelected(int index);
    void languageSelected(int language);
    void voiceSelected(int index);
    void localeChanged(const QLocale &locale);
//! [1.语音功能部分]

  private slots:
    void on_btn_itemMonitoring_clicked();
    void on_btn_itemHistory_clicked();
    void on_btn_opcua_clicked();
    void on_btn_voice_clicked();
    void on_toolBox_currentChanged(int index);
    void on_btn_exit_clicked();
    void on_btn_save_opcserver_parameter_clicked();
    void on_btn_additem_clicked();

//! [4.OPCUA服务器功能]
  private slots:
    // 创建客户端+连接、断开服务器连接
    void connectToServer();
    void showErrorDialog(QOpcUaErrorState *errorState);
    // 获取服务器OPCUA服务接口
    void findServers();
    // 槽函数，返回可用OPCUA服务接口列表
    void findServersComplete(const QList<QOpcUaApplicationDescription> &servers, QOpcUa::UaStatusCode statusCode);
    // 获取OPCUA服务支持的认证模式
    void getEndpoints();
    // 槽函数，返回可用认证模式列表
    void getEndpointsComplete(const QList<QOpcUaEndpointDescription> &endpoints, QOpcUa::UaStatusCode statusCode);
//! [4.OPCUA服务器功能]

    // 槽函数，TableView当前值改变信号
    void doItemChanged(QStandardItem * item);
    // 向TableView添加订阅记录
    void addItem(bool enable, QString browName, QString nodeId, QString condition, QString condValue, QString voiceTxt, QString interval, bool showFlag);

    void doShowChart();
    void openCustomContextMenu(const QPoint &point);

    void on_btn_saveitem_clicked();

    void on_btn_deleteitem_clicked();

    void on_spinBox_rec_count_valueChanged(int arg1);

    void on_btn_page_search_clicked();

    void on_btn_page_frist_clicked();

    void on_btn_page_pre_clicked();

    void on_btn_page_next_clicked();

    void on_btn_page_end_clicked();

    void on_saveButton_clicked();

    void on_btn_to_json_clicked();

    void on_btn_from_json_clicked();

    void on_btn_clock_clicked();

    void on_btn_chart_clicked();

    void on_btn_other_clicked();

    void on_btn_point_count_x_clicked();

    void on_spinBox_point_count_x_valueChanged(int arg1);

    void on_stackedWidget_currentChanged(int arg1);


    void on_spinBox_say_max_count_valueChanged(int arg1);

    void on_btn_say_max_count_save_clicked();

  private:
    Ui::MainWindow *ui;

    bool mClientConnected = false;
    // 首次执行标志
    bool firstRun = true;
    QLabel label_pixmap, label_speak, *label_date;
    QPixmap *connectIco;                // 图片：已连接
    QPixmap *disconnectIco;
    QPixmap *speak, *speakIco, *speak_pasue;
    QOpcUaProvider *m_provider;
    QStandardItemModel *m_model;
    QItemSelectionModel *m_selection;
    QOpcUaClient *m_client = nullptr;
    QOpcUaNode* m_node;
    // OPCUA服务支持的认证模式
    QList<QOpcUaEndpointDescription> mEndpointList;
    QOpcUaApplicationIdentity m_identity;
    QOpcUaPkiConfiguration m_pkiConfig;
    // 当前连接的认证模式
    QOpcUaEndpointDescription m_endpoint;

    QTextToSpeech *m_speech = nullptr;
    QList<QVoice> m_voices;
    QSqlDatabase db;
    QSqlQueryModel qryModel;
    QMenu *mContextMenu;
    QAction *mContextMenuShowChartAction;

    int toolbox_monitoring_current_index = 0,
        toolbox_setting_current_index = 0,
        // 服务器中可用OPCUA安全认证模式序号
        opc_endpoint_index = 0,
        // 服务器中可用OPCUA服务序号
        opc_server_index = 0,
        // 报警记录的当前页
        history_current_page = 1,
        // 报警记录每页显示多少条记录
        history_rec_count_page = 20,
        // 报警记录总页数
        history_pages = 0,
        point_count_x = 120,
        say_max_count = 1;
    //服务器时间
    QString opc_server_time,
            // 服务器的URL
            opc_server_url = "opc.tcp://127.0.0.1:49320";
    // 添加需要监控的项目选择页面
    AddAlarmDialog *alarmDialog;
    QList<FromChartView *>frmChartViewN;

    QWIntSpinDelegate doubleSpinDelegate;
    QwComboBoxDelegate comboBoxDelegate;
    QWTextEditDelegate textEditDelegate;
    MyDelegate lineEditDelegate;

  private:
    void onEngineReady();
    // 连接数据库+创建数据表+初始化程序参数
    void connectToDatabase();
    // 创建OPCUA客户端，若干OPCUA客户端信号与槽函数关联
    void createOpcuaClient();
    void setupPkiConfiguration();
    // 更新界面部件显示状态
    void updateUiState();
    // 清空TableView订阅记录
    void clearItem();
    // 将TableView的内容保存到数据库
    void saveTableView();
    // 将数据库的内容导入到TableView中
    void loadTableView();
    // 保存报警记录到数据库中
    void addAlarmInfo(QString browseName, QString nodeId, QString info);
    void showHistory();
    // 刷新报警记录中的NodeId清单，数据库过滤用
    void refreshNodeId();
    // 刷新报警记录页面按钮状态
    void updateHistoryBtnState();
    // 将项目清单导出到文件
    void viewToJson();
    // 从文件中将项目清单导入
    void viewFromJson();
    // 订阅OPCUA服务器时间
    void subscribeOpcUaDate();
    // 检查所有监控项目，根据显示标志showFlag，生成需要显示的列表类frmChartViewN
    void refreshChartView();
    // 趋势图表界面根据窗口大小排列组件布局
    void adjustLayout();

};
#endif // MAINWINDOW_H
